﻿using ArcGIS.Core.CIM;
using ArcGIS.Core.Data;
using ArcGIS.Core.Geometry;
using ArcGIS.Core.Internal.CIM;
using ArcGIS.Desktop.Core;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Internal.Framework.Utilities;
using ArcGIS.Desktop.Mapping;
using Aspose.Cells;
using CCTool.Scripts.Manager;
using CCTool.Scripts.ToolManagers;
using CCTool.Scripts.ToolManagers.Extensions;
using CCTool.Scripts.ToolManagers.Managers;
using MathNet.Numerics;
using MathNet.Numerics.LinearAlgebra.Factorization;
using NPOI.POIFS.Crypt.Dsig;
using NPOI.SS.Formula.Functions;
using NPOI.SS.Formula.PTG;
using NPOI.SS.UserModel;
using NPOI.SS.Util;
using NPOI.XSSF.UserModel;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Polygon = ArcGIS.Core.Geometry.Polygon;
using Range = Aspose.Cells.Range;

namespace CCTool.Scripts.CusTool4
{
    /// <summary>
    /// Interaction logic for QJDCExcel2.xaml
    /// </summary>
    public partial class QJDCExcel2 : ArcGIS.Desktop.Framework.Controls.ProWindow
    {
        // 工具设置标签
        readonly string toolSet = "QJDCExcel2";
        public QJDCExcel2()
        {
            InitializeComponent();

            // 初始化参数选项
            textFolderPath.Text = BaseTool.ReadValueFromReg(toolSet, "excel_folder");
        }

        // 更新默认字段
        public async void UpdataField()
        {
            string ly = combox_fc.ComboxText();

            // 初始化参数选项

            await UITool.InitLayerFieldToComboxPlus(combox_qlr, ly, "权利人", "string");
            await UITool.InitLayerFieldToComboxPlus(combox_zl, ly, "坐落", "string");
            await UITool.InitLayerFieldToComboxPlus(combox_fl, ly, "法人", "string");
            await UITool.InitLayerFieldToComboxPlus(combox_sfz, ly, "身份证", "string");
            await UITool.InitLayerFieldToComboxPlus(combox_zsbh, ly, "证书编", "string");
            await UITool.InitLayerFieldToComboxPlus(combox_zdmj, ly, "MJ", "float");

            await UITool.InitLayerFieldToComboxPlus(combox_txdz, ly, "TXDZ", "string");
            await UITool.InitLayerFieldToComboxPlus(combox_frdh, ly, "电话", "string");


            await UITool.InitLayerFieldToComboxPlus(combox_bz, ly, "ZDSZB", "string");
            await UITool.InitLayerFieldToComboxPlus(combox_dz, ly, "ZDSZD", "string");
            await UITool.InitLayerFieldToComboxPlus(combox_nz, ly, "ZDSZN", "string");
            await UITool.InitLayerFieldToComboxPlus(combox_xz, ly, "ZDSZX", "string");

        }


        // 定义一个进度框
        private ProcessWindow processwindow = null;
        string tool_name = "权籍调查表(不知道)";

        private void combox_fc_DropDown(object sender, EventArgs e)
        {
            UITool.AddFeatureLayersToComboxPlus(combox_fc);
        }

        private void openFolderButton_Click(object sender, RoutedEventArgs e)
        {
            textFolderPath.Text = UITool.OpenDialogFolder();
        }

        // 获取字段值，如无则为""
        private string GetFieldValue(Feature feature, string fieldName)
        {
            string result = "";

            if (fieldName is not null && fieldName != "")
            {
                result = feature[fieldName]?.ToString();

                if (fieldName is null)
                {
                    result = "";
                }
            }

            return result;
        }


        private async void btn_go_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                // 参数获取
                string in_fc = combox_fc.ComboxText();
                string excel_folder = textFolderPath.Text;


                string field_qlr = combox_qlr.ComboxText();
                string field_zl = combox_zl.ComboxText();
                string field_fl = combox_fl.ComboxText();
                string field_sfz = combox_sfz.ComboxText();
                string field_zsbh = combox_zsbh.ComboxText();
                string field_zdmj = combox_zdmj.ComboxText();

                string field_txdz = combox_txdz.ComboxText();
                string field_frdh = combox_frdh.ComboxText();

                string field_bz = combox_bz.ComboxText();
                string field_dz = combox_dz.ComboxText();
                string field_nz = combox_nz.ComboxText();
                string field_xz = combox_xz.ComboxText();

                // 判断参数是否选择完全
                if (in_fc == "" || excel_folder == "")
                {
                    MessageBox.Show("有必选参数为空！！！");
                    return;
                }

                // 写入本地
                BaseTool.WriteValueToReg(toolSet, "excel_folder", excel_folder);

                // 打开进度框
                ProcessWindow pw = UITool.OpenProcessWindow(processwindow, tool_name);
                pw.AddMessageTitle(tool_name);

                Close();

                await QueuedTask.Run(() =>
                {
                    pw.AddMessageStart("获取目标FeatureLayer");
                    // 获取目标FeatureLayer
                    FeatureLayer featurelayer = in_fc.TargetFeatureLayer();
                    // 确保要素类的几何类型是多边形
                    if (featurelayer.ShapeType != esriGeometryType.esriGeometryPolygon)
                    {
                        // 如果不是多边形类型，则输出错误信息并退出函数
                        MessageBox.Show("该要素类不是多边形类型。");
                        return;
                    }

                    // 遍历面要素类中的所有要素
                    RowCursor cursor = featurelayer.TargetSelectCursor();
                    while (cursor.MoveNext())
                    {
                        using var feature = cursor.Current as Feature;
                        Polygon polygon = feature.GetShape() as Polygon;

                        // 获取参数
                        long oid = feature.GetObjectID();

                        string qlr = GetFieldValue(feature, field_qlr);
                        string zl = GetFieldValue(feature, field_zl);
                        string fl = GetFieldValue(feature, field_fl);
                        string sfz = GetFieldValue(feature, field_sfz);
                        string zsbh = GetFieldValue(feature, field_zsbh);
                        string zdmj = GetFieldValue(feature, field_zdmj);

                        string txdz = GetFieldValue(feature, field_txdz);
                        string frdh = GetFieldValue(feature, field_frdh);

                        string bz = GetFieldValue(feature, field_bz);
                        string dz = GetFieldValue(feature, field_dz);
                        string nz = GetFieldValue(feature, field_nz);
                        string xz = GetFieldValue(feature, field_xz);

                        pw.AddMessageMiddle(20, $"处理要素：{oid} - 权利人：{qlr}");

                        // 复制界址点Excel表
                        string excelPath = excel_folder + @$"\权籍调查表_{oid}_{qlr}.xls";
                        DirTool.CopyResourceFile(@"CCTool.Data.Excel.杂七杂八.权籍调查表模板2.xls", excelPath);

                        // 打开工作薄
                        Workbook wb = ExcelTool.OpenWorkbook(excelPath);

                        // 处理sheet_基本表
                        Worksheet ws_jbb = wb.Worksheets["基本表"];
                        Cells cells_jbb = ws_jbb.Cells;
                        cells_jbb["D4"].Value = $"{qlr}";
                        cells_jbb["H6"].Value = $"{sfz}";
                        cells_jbb["H7"].Value = $"{txdz}";
                        cells_jbb["H8"].Value = $"{zsbh}";
                        cells_jbb["C10"].Value = $"{zl}";

                        cells_jbb["H11"].Value = $"{frdh}";

                        cells_jbb["C11"].Value = $"{fl}";
                        cells_jbb["E12"].Value = $"{sfz}";

                        cells_jbb["C20"].Value = $"北：{bz}";
                        cells_jbb["C21"].Value = $"东：{dz}";
                        cells_jbb["C22"].Value = $"南：{nz}";
                        cells_jbb["C23"].Value = $"西：{xz}";

                        cells_jbb["B27"].Value = $"{zdmj}";
                        cells_jbb["E27"].Value = $"{zdmj}";

                        // 保存
                        wb.Save(excelPath);
                        wb.Dispose();


                        // 界址标示表
                        JZBSB($@"{excelPath}\界址标示表$", polygon);

                        // 界址标示表
                        JZQZB($@"{excelPath}\界址签章表$", polygon);

                    }


                    pw.AddMessageEnd();
                });
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.Message + ee.StackTrace);
                return;
            }
        }


        // 界址标示表
        private void JZBSB(string excelPath, Polygon polygon)
        {
            // 获取工作薄、工作表
            string excelFile = ExcelTool.GetPath(excelPath);
            int sheetIndex = ExcelTool.GetSheetIndex(excelPath);
            // 打开工作薄
            Workbook wb = ExcelTool.OpenWorkbook(excelFile);
            // 处理sheet
            Worksheet ws = wb.Worksheets[sheetIndex];
            Cells cells = ws.Cells;

            // 获取面要素的所有折点【按西北角起始，顺时针重排】
            List<List<MapPoint>> mapPoints = polygon.ReshotMapPoint();

            // 设置分页信息
            SetPage(mapPoints, cells);


            int index = 5;   // 起始行
            int pointIndex = 1;  // 起始点序号
            int lastRowCount = 0;  // 上一轮的行数
            int ptDigit = 2;

            for (int i = 0; i < mapPoints.Count; i++)
            {
                // 输出折点的XY值和距离到Excel表
                double prevX = double.NaN;
                double prevY = double.NaN;

                for (int j = 0; j < mapPoints[i].Count; j++)
                {
                    // 写入点号
                    if (index > 5)
                    {
                        if (pointIndex - lastRowCount == mapPoints[i].Count)    // 找到当前环的最后一点
                        {
                            cells[index, 0].Value = $"J{lastRowCount + 1 - i}";
                        }
                        else
                        {
                            cells[index, 0].Value = $"J{pointIndex - i}";
                        }
                    }
                    else
                    {
                        cells[index, 0].Value = $"J1";
                    }

                    // 写入勾
                    cells[index, 5].Value = $"√";


                    double x = Math.Round(mapPoints[i][j].X, ptDigit);
                    double y = Math.Round(mapPoints[i][j].Y, ptDigit);

                    // 计算当前点与上一个点的距离
                    if (!double.IsNaN(prevX) && !double.IsNaN(prevY) && index > 3)
                    {
                        string distance = Math.Sqrt(Math.Pow(x - prevX, 2) + Math.Pow(y - prevY, 2)).RoundWithFill(ptDigit);
                        // 写入距离【第一行不写入】
                        if (index % 49 == 5)
                        {
                            cells[index - 8, 8].Value = distance;
                            cells[index - 8, 19].Value = $"√";
                        }
                        else if (index % 49 == 7)
                        {
                            cells[index - 2, 8].Value = distance;
                            cells[index - 2, 19].Value = $"√";
                        }
                        else
                        {
                            cells[index - 1, 8].Value = distance;
                            cells[index - 1, 19].Value = $"√";
                        }
                    }
                    prevX = x;
                    prevY = y;

                    // 行变化
                    if (index % 49 == 45)
                    {
                        index += 9;
                    }
                    else
                    {
                        index += 2;
                    }

                    pointIndex++;
                }
                lastRowCount += mapPoints[i].Count;
            }


            // 保存
            wb.Save(excelFile);
            wb.Dispose();

        }

        // 界址签章表
        private void JZQZB(string excelPath, Polygon polygon)
        {
            // 获取工作薄、工作表
            string excelFile = ExcelTool.GetPath(excelPath);
            int sheetIndex = ExcelTool.GetSheetIndex(excelPath);
            // 打开工作薄
            Workbook wb = ExcelTool.OpenWorkbook(excelFile);
            // 处理sheet
            Worksheet ws = wb.Worksheets[sheetIndex];
            Cells cells = ws.Cells;

            // 获取面要素的所有折点【按西北角起始，顺时针重排】
            List<List<MapPoint>> mapPoints = polygon.ReshotMapPoint();

            // 设置分页信息
            SetPage2(mapPoints, cells);


            int index = 4;   // 起始行
            int pointIndex = 1;  // 起始点序号
            int lastRowCount = 0;  // 上一轮的行数

            for (int i = 0; i < mapPoints.Count; i++)
            {
                for (int j = 0; j < mapPoints[i].Count; j++)
                {
                    // 判断是否最后一个点
                    bool isLastPoint = false;
                    
                    if (i == mapPoints.Count-1 && j == mapPoints[^1].Count-1)
                    {
                        isLastPoint = true;
                    }
                    
                    // 写入点号
                    if (index > 4)
                    {
                        int lastRow = index % 31 == 0 ? 4 : 1;    // 考虑跨页

                        if (pointIndex - lastRowCount == mapPoints[i].Count)    // 找到当前环的最后一点
                        {
                            if (!isLastPoint)
                            {
                                cells[index, 0].Value = $"J{lastRowCount + 1 - i}";
                            }
                            cells[index - lastRow, 2].Value = $"J{lastRowCount + 1 - i}";

                        }
                        else
                        {
                            if (!isLastPoint)
                            {
                                cells[index, 0].Value = $"J{pointIndex - i}";
                            }

                            cells[index - lastRow, 2].Value = $"J{pointIndex - i}";
                        }
                    }
                    else
                    {
                        cells[index, 0].Value = $"J1";
                    }

                    // 写入横线
                    if (!isLastPoint)
                    {
                        cells[index, 1].Value = $"——";
                    }

                    // 行变化
                    if (index % 27 == 0)
                    {
                        index += 4;
                    }
                    else
                    {
                        index ++;
                    }

                    pointIndex++;
                }
                lastRowCount += mapPoints[i].Count;
            }


            // 保存
            wb.Save(excelFile);
            wb.Dispose();

        }

        // 生成分页，并设置分页信息
        public static void SetPage(List<List<MapPoint>> mapPoints, Cells cells)
        {
            // 获取要素的界址点总数
            long pointsCount = 0;
            foreach (var pts in mapPoints)
            {
                pointsCount += pts.Count;
            }

            // 计算要生成的页数
            long pageCount = (int)Math.Ceiling((double)pointsCount / 21);

            if (pageCount > 1)   // 多于2页，就复制
            {
                // 复制分页，前两页已有不用复制
                for (int i = 1; i < pageCount; i++)
                {
                    cells.CopyRows(cells, 0, 49 * i, 49);
                }
            }
        }

        // 生成分页，并设置分页信息
        public static void SetPage2(List<List<MapPoint>> mapPoints, Cells cells)
        {
            // 获取要素的界址点总数
            long pointsCount = 0;
            foreach (var pts in mapPoints)
            {
                pointsCount += pts.Count;
            }

            // 计算要生成的页数
            long pageCount = (int)Math.Ceiling((double)pointsCount / 21);

            if (pageCount > 1)   // 多于2页，就复制
            {
                // 复制分页，前两页已有不用复制
                for (int i = 1; i < pageCount; i++)
                {
                    cells.CopyRows(cells, 0, 27 * i, 27);
                }
            }
        }

        private void btn_help_Click(object sender, RoutedEventArgs e)
        {
            string url = "https://blog.csdn.net/xcc34452366/article/details/148953128";
            UITool.Link2Web(url);
        }


        private void combox_qlr_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_qlr);
        }

        private void combox_zl_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_zl);
        }

        private void combox_fl_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_fl);
        }

        private void combox_sfz_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_sfz);
        }

        private void combox_zdmj_DropDown(object sender, EventArgs e)
        {
            UITool.AddFloatFieldsToComboxPlus(combox_fc.ComboxText(), combox_zdmj);
        }

        private void combox_bz_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_bz);
        }

        private void combox_dz_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_dz);
        }

        private void combox_nz_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_nz);
        }

        private void combox_xz_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_xz);
        }



        private void combox_txdz_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_txdz);
        }

        private void combox_frdh_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_frdh);
        }

        private void combox_fc_DropClose(object sender, EventArgs e)
        {
            // 更新默认字段
            UpdataField();
        }

        private void combox_zsbh_DropDown(object sender, EventArgs e)
        {
            UITool.AddTextFieldsToComboxPlus(combox_fc.ComboxText(), combox_zsbh);
        }
    }
}
